package com.jcxh.sg_exam.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jcxh.sg_exam.pojo.*;
import com.jcxh.sg_exam.pojo.dto.UpdateKaochangDto;
import com.jcxh.sg_exam.pojo.dto.UserDto;
import com.jcxh.sg_exam.pojo.vo.*;
import com.jcxh.sg_exam.service.*;
import com.jcxh.sg_exam.utils.BCrypt;
import com.jcxh.sg_exam.utils.JwtUtils;
import com.jcxh.sg_exam.utils.RedisCacheService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author 鹏少
 * @Date 2024/8/14
 * @Date 13:47
 */
@Api(tags = "用户端接口")
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {


    @Autowired
    private UserService userService;
    @Autowired
    private KaochangService kaochangService;
    @Autowired
    private KaochangUserService kaochangUserService;
    @Autowired
    private UserTitleService userTitleService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RedisCacheService redisCacheService;
    @Autowired
    private DanxuanService danxuanService;
    @Autowired
    private DuoxuanService duoxuanService;
    @Autowired
    private PanduanService panduanService;

    @ApiOperation(value = "用户登录")
    @PostMapping("/login")
    public Result login(@RequestBody UserDto userDto) {

        // log.info("{}线程执行了用户登录",Thread.currentThread().getName());
        if (StringUtils.isBlank(userDto.getIdNumber()) || StringUtils.isBlank(userDto.getPassword())) {
            return Result.error("请输入账号密码进行登录");
        }

        // 查询用户有哪些考场
        List<KaochangUser> list = kaochangUserService.lambdaQuery().eq(KaochangUser::getIdNumber, userDto.getIdNumber()).list();


        // 检查用户是否存在以及是否分配了考场
        if (list.isEmpty()) {
            return Result.error("未分配考场, 请联系相应管理人员");
        }


        User user = JSONObject.parseObject(redisCacheService.get(userDto.getIdNumber()), User.class);
        if (user == null) {
            user = userService.lambdaQuery().eq(User::getIdNumber, userDto.getIdNumber()).one();
        }

        // 验证密码
        boolean isPasswordValid = BCrypt.checkpw(userDto.getPassword(), user.getPassword());
        if (!isPasswordValid) {
            return Result.error("密码错误");
        }

        // 清除密码
        user.setPassword("");

        // 生成 JWT token
        String token = generateTokenForUser(user);

        // 记录登录信息
        //log.info("用户端id为{}的用户 登录生成的token为:{}", user.getId(), token);

        // 返回成功结果
        Map<String, Object> response = new HashMap<>();
        response.put("user", user);
        response.put("token", token);

        return Result.success(response);
    }

    private String generateTokenForUser(User user) {
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        return JwtUtils.generateJwt(map);
    }


    //查询用户全部考场
    @ApiOperation(value = "查询用户全部考场")
    @GetMapping("/getUserKaoChangs")
    public Result getUserKaoChangs(@ApiParam(value = "用户id,参数名userId", required = true) Integer userId) {

//        User user = UserThreadLocalUtil.getUser();
//        Integer userId = user.getId();
        List<UserKaochangVo> list = userService.getUserKaoChangs(userId);
        return Result.success(list);

    }


    //实际传入的为kaochang的id
    @ApiOperation(value = "开始答题按钮")
    @GetMapping("/start")
    @Transactional
    public Result start(@ApiParam(value = "id(实际传入的为kaochang的id)") Integer id,
                        @ApiParam(value = "用户id,参数名userId", required = true) Integer userId) {


        String lockKey = "lock:start_exam:user_" + userId + "_kaochang_" + id;
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String lockValue = UUID.randomUUID().toString();

        int retryTimes = 5; // 最多重试次数
        int waitMillis = 80; // 每次等待毫秒数

        for (int i = 0; i < retryTimes; i++) {
            Boolean isLocked = ops.setIfAbsent(lockKey, lockValue, Duration.ofSeconds(30));
            if (Boolean.TRUE.equals(isLocked)) {
                try {
                    // 原来的业务逻辑

                    KaochangUser kaochangUser = kaochangUserService.lambdaQuery()
                            .eq(KaochangUser::getUserId, userId)
                            .eq(KaochangUser::getKaochangId, id).one();

                    if (kaochangUser.getScore() != null) {
                        return Result.error("您已答题完毕,感谢使用!");
                    }

                    Kaochang realKaochang = kaochangService.lambdaQuery().eq(Kaochang::getId, id).one();
                    LocalDateTime now = LocalDateTime.now();
                    if (!(now.isBefore(realKaochang.getEndTime()) && now.isAfter(realKaochang.getStartTime()))) {
                        return Result.error("请在规定时间内进行答题");
                    }

                    List<UserTitle> list = userTitleService.lambdaQuery().eq(UserTitle::getUserId, userId).list();
                    List<UserTitle> alreadyExistTitle = list.stream()
                            .filter(s -> !s.getKaochangId().equals(id))
                            .collect(Collectors.toList());
                    List<Integer> alreadyExistKaochangId = alreadyExistTitle.stream()
                            .map(UserTitle::getKaochangId)
                            .distinct()
                            .collect(Collectors.toList());

                    for (Integer integer : alreadyExistKaochangId) {
                        KaochangUser selectWhetherExistScore = kaochangUserService.lambdaQuery()
                                .eq(KaochangUser::getUserId, userId)
                                .eq(KaochangUser::getKaochangId, integer).one();
                        if (selectWhetherExistScore.getScore() == null) {
                            return Result.error("请提交" + selectWhetherExistScore.getKaochangName() + "的试卷,再来进行答题");
                        }
                    }

                    List<Danxuan> danxuanList = redisTemplate.opsForList().range("danXuan", 0, -1);
                    if (danxuanList == null || danxuanList.isEmpty()) {
                        danxuanList = danxuanService.list();
                    }
                    List<Duoxuan> duoxuanList = redisTemplate.opsForList().range("duoXuan", 0, -1);
                    if (duoxuanList == null || duoxuanList.isEmpty()) {
                        duoxuanList = duoxuanService.list();
                    }
                    List<Panduan> panduanList = redisTemplate.opsForList().range("panDuan", 0, -1);
                    if (panduanList == null || panduanList.isEmpty()) {
                        panduanList = panduanService.list();
                    }

                    String type = realKaochang.getType();

                    List<UserTitle> userTitleList = userTitleService.lambdaQuery()
                            .eq(UserTitle::getUserId, userId)
                            .eq(UserTitle::getKaochangId, id).list();

                    if (!userTitleList.isEmpty()) {
                        Map<String, Set<Integer>> titlesByType = userTitleList.stream()
                                .sorted(Comparator.comparing(UserTitle::getOrderId))
                                .collect(Collectors.groupingBy(UserTitle::getType,
                                        Collectors.mapping(UserTitle::getTitleId, Collectors.toSet())));

                        Set<Integer> danxuan = titlesByType.getOrDefault("1", Collections.emptySet());
                        Set<Integer> duoxuan = titlesByType.getOrDefault("2", Collections.emptySet());
                        Set<Integer> panduan = titlesByType.getOrDefault("3", Collections.emptySet());

                        List<Danxuan> filteredDanxuanList = danxuanList.stream()
                                .filter(s -> danxuan.contains(s.getId()))
                                .collect(Collectors.toList());
                        List<Duoxuan> filteredDuoxuanList = duoxuanList.stream()
                                .filter(s -> duoxuan.contains(s.getId()))
                                .collect(Collectors.toList());
                        List<Panduan> filteredPanduanList = panduanList.stream()
                                .filter(s -> panduan.contains(s.getId()))
                                .collect(Collectors.toList());

                        List<UserDanxuanVo> danxuanVoList = filteredDanxuanList.stream().map(s -> {
                            UserDanxuanVo userDanxuanVo = new UserDanxuanVo();
                            BeanUtils.copyProperties(s, userDanxuanVo);
                            userDanxuanVo.setKaochangId(id);
                            userDanxuanVo.setAnswer("");
                            userDanxuanVo.setUserAnswer(getRealAnswerForDanxuan(s, userTitleList, userId, id));
                            return userDanxuanVo;
                        }).collect(Collectors.toList());

                        List<UserDuoxuanVo> duoxuanVoList = filteredDuoxuanList.stream().map(s -> {
                            UserDuoxuanVo userDuoxuanVo = new UserDuoxuanVo();
                            BeanUtils.copyProperties(s, userDuoxuanVo);
                            userDuoxuanVo.setKaochangId(id);
                            userDuoxuanVo.setAnswer("");
                            userDuoxuanVo.setUserAnswer(getRealAnswerForDuoxuan(s, userTitleList, userId, id));
                            return userDuoxuanVo;
                        }).collect(Collectors.toList());

                        List<UserPanduanVo> panduanVoList = filteredPanduanList.stream().map(s -> {
                            UserPanduanVo userPanduanVo = new UserPanduanVo();
                            BeanUtils.copyProperties(s, userPanduanVo);
                            userPanduanVo.setKaochangId(id);
                            userPanduanVo.setAnswer("");
                            userPanduanVo.setUserAnswer(getRealAnswerForPanduan(s, userTitleList, userId, id));
                            return userPanduanVo;
                        }).collect(Collectors.toList());

                        Map<String, List> map = new HashMap<>();
                        map.put("danxuan", danxuanVoList);
                        map.put("duoxuan", duoxuanVoList);
                        map.put("panduan", panduanVoList);
                        return Result.success(map);

                    } else {

                        List<Danxuan> danxuan = danxuanList.stream()
                                .filter(s -> s.getType().equals(type))
                                .collect(Collectors.toList());
                        List<Duoxuan> duoxuan = duoxuanList.stream()
                                .filter(s -> s.getType().equals(type))
                                .collect(Collectors.toList());
                        List<Panduan> panduan = panduanList.stream()
                                .filter(s -> s.getType().equals(type))
                                .collect(Collectors.toList());

                        Collections.shuffle(danxuan);
                        Collections.shuffle(duoxuan);
                        Collections.shuffle(panduan);

                        List<Danxuan> selectedDanxuan = danxuan.stream()
                                .limit(50)
                                .sorted(Comparator.comparing(Danxuan::getId))
                                .collect(Collectors.toList());
                        List<Duoxuan> selectedDuoxuan = duoxuan.stream()
                                .limit(10)
                                .sorted(Comparator.comparing(Duoxuan::getId))
                                .collect(Collectors.toList());
                        List<Panduan> selectedPanduan = panduan.stream()
                                .limit(30)
                                .sorted(Comparator.comparing(Panduan::getId))
                                .collect(Collectors.toList());

                        List<UserTitle> collect1 = selectedDanxuan.stream().map(s -> {
                            UserTitle userTitle = new UserTitle();
                            userTitle.setUserId(userId);
                            userTitle.setType("1");
                            userTitle.setKaochangId(id);
                            userTitle.setTitleId(s.getId());
                            userTitle.setRealAnswer(s.getAnswer());
                            userTitle.setCreateTime(LocalDateTime.now());
                            return userTitle;
                        }).collect(Collectors.toList());

                        List<UserTitle> collect2 = selectedDuoxuan.stream().map(s -> {
                            UserTitle userTitle = new UserTitle();
                            userTitle.setUserId(userId);
                            userTitle.setType("2");
                            userTitle.setKaochangId(id);
                            userTitle.setTitleId(s.getId());
                            userTitle.setRealAnswer(s.getAnswer());
                            userTitle.setCreateTime(LocalDateTime.now());
                            return userTitle;
                        }).collect(Collectors.toList());

                        List<UserTitle> collect3 = selectedPanduan.stream().map(s -> {
                            UserTitle userTitle = new UserTitle();
                            userTitle.setUserId(userId);
                            userTitle.setType("3");
                            userTitle.setKaochangId(id);
                            userTitle.setTitleId(s.getId());
                            userTitle.setRealAnswer(s.getAnswer());
                            userTitle.setCreateTime(LocalDateTime.now());
                            return userTitle;
                        }).collect(Collectors.toList());

                        List<UserTitle> mergedList = Stream.of(collect1, collect2, collect3)
                                .flatMap(List::stream)
                                .collect(Collectors.toList());

                        for (int j = 0; j < mergedList.size(); j++) {
                            mergedList.get(j).setOrderId(String.valueOf(j + 1));
                        }

                        try {
                            userTitleService.saveBatch(mergedList);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        List<UserDanxuanVo> danxuanVoList = selectedDanxuan.stream().map(s -> {
                            UserDanxuanVo userDanxuanVo = new UserDanxuanVo();
                            BeanUtils.copyProperties(s, userDanxuanVo);
                            userDanxuanVo.setAnswer("");
                            userDanxuanVo.setAnalysis("");
                            userDanxuanVo.setKaochangId(id);
                            return userDanxuanVo;
                        }).collect(Collectors.toList());

                        List<UserDuoxuanVo> duoxuanVoList = selectedDuoxuan.stream().map(s -> {
                            UserDuoxuanVo userDuoxuanVo = new UserDuoxuanVo();
                            BeanUtils.copyProperties(s, userDuoxuanVo);
                            userDuoxuanVo.setAnswer("");
                            userDuoxuanVo.setAnalysis("");
                            userDuoxuanVo.setKaochangId(id);
                            return userDuoxuanVo;
                        }).collect(Collectors.toList());

                        List<UserPanduanVo> panduanVoList = selectedPanduan.stream().map(s -> {
                            UserPanduanVo userPanduanVo = new UserPanduanVo();
                            BeanUtils.copyProperties(s, userPanduanVo);
                            userPanduanVo.setAnswer("");
                            userPanduanVo.setAnalysis("");
                            userPanduanVo.setKaochangId(id);
                            return userPanduanVo;
                        }).collect(Collectors.toList());

                        Map<String, List> map = new HashMap<>();
                        map.put("danxuan", danxuanVoList);
                        map.put("duoxuan", duoxuanVoList);
                        map.put("panduan", panduanVoList);

                        KaochangUser realKaochangUser = kaochangUserService.lambdaQuery()
                                .eq(KaochangUser::getUserId, userId)
                                .eq(KaochangUser::getKaochangId, id).one();
                        if (realKaochangUser.getLoginTime() == null) {
                            kaochangUserService.lambdaUpdate()
                                    .set(KaochangUser::getLoginTime, LocalDateTime.now())
                                    .eq(KaochangUser::getUserId, userId)
                                    .eq(KaochangUser::getKaochangId, id)
                                    .update();
                        }

                        return Result.success(map);

                    }

                    // 原有逻辑结束

                } finally {
                    Object currentValue = redisTemplate.opsForValue().get(lockKey);
                    if (lockValue.equals(currentValue)) {
                        redisTemplate.delete(lockKey); // 释放锁
                    }
                }
            } else {
                try {
                    Thread.sleep(waitMillis);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return Result.error("操作中断");
                }
            }
        }

        return Result.error("系统繁忙，请稍后再试");
    }




    private String getRealAnswerForDanxuan(Danxuan danxuan, List<UserTitle> userTitleList, Integer userId, Integer id) {

        UserTitle userTitle = userTitleList.stream()
                .filter(s -> danxuan.getId().equals(s.getTitleId()) && s.getType().equals("1")
                        && s.getUserId().equals(userId)
                        && s.getKaochangId().equals(id)).findFirst().orElse(null);


        return userTitle != null ? userTitle.getUserAnswer() : null;
    }

    private String getRealAnswerForDuoxuan(Duoxuan duoxuan, List<UserTitle> userTitleList, Integer userId, Integer id) {
        UserTitle userTitle = userTitleList.stream()
                .filter(s -> duoxuan.getId().equals(s.getTitleId()) && s.getType().equals("2")
                        && s.getUserId().equals(userId)
                        && s.getKaochangId().equals(id)).findFirst().orElse(null);


        return userTitle != null ? userTitle.getUserAnswer() : null;
    }

    private String getRealAnswerForPanduan(Panduan panduan, List<UserTitle> userTitleList, Integer userId, Integer id) {
        UserTitle userTitle = userTitleList.stream()
                .filter(s -> panduan.getId().equals(s.getTitleId()) && s.getType().equals("3")
                        && s.getUserId().equals(userId)
                        && s.getKaochangId().equals(id)).findFirst().orElse(null);


        return userTitle != null ? userTitle.getUserAnswer() : null;
    }


    @ApiOperation("上一题下一题按钮")
    @GetMapping("/dati")
    public Result dati(@ApiParam(value = "用户id,参数名userId", required = true) Integer userId,
                       @ApiParam(required = true, value = "考题id") Integer id,
                       @ApiParam(required = true, value = "考场id") Integer kaochangId,
                       @ApiParam(required = true, value = "类型(1单选 2多选 3判断)") Integer type,
                       @ApiParam(value = "用户答案") String answer) {

//        User user = UserThreadLocalUtil.getUser();
//        Integer userId = user.getId();

        if (answer == null) {
            return Result.success();
        }
        userTitleService.lambdaUpdate()
                .set(answer != null, UserTitle::getUserAnswer, answer)
                .set(UserTitle::getStartTime, LocalDateTime.now())
                //更新时间暂时不设置
                // .set(UserTitle::getUpdateTime, LocalDateTime.now())
                .eq(UserTitle::getKaochangId, kaochangId)
                .eq(UserTitle::getUserId, userId)
                .eq(UserTitle::getType, type)
                .eq(UserTitle::getTitleId, id).update();

        return Result.success();
    }


    @ApiOperation("交卷")
    @GetMapping("/submit")
    @Transactional
    public Result submit(@ApiParam(required = true, value = "考场id") Integer kaochangId,
                         @ApiParam(value = "用户id,参数名userId", required = true) Integer userId) {


        KaochangUser kaochangUser = kaochangUserService.lambdaQuery()
                .eq(KaochangUser::getUserId, userId)
                .eq(KaochangUser::getKaochangId, kaochangId).one();

        if (kaochangUser.getScore() != null) {
            return Result.error("请勿重复提交");
        }
//        if (userId == null) {
//            throw new IllegalStateException("线程中没发现用户");
//        }
        //Integer userId = user.getId();

        List<UserTitle> userTitleList = userTitleService.lambdaQuery()
                .eq(UserTitle::getKaochangId, kaochangId)
                .eq(UserTitle::getUserId, userId)
                .list();

        // 使用 HashMap 代替 Map.of
//        Map<String, Integer> typeToScoreMap = new HashMap<>();
//        typeToScoreMap.put("1", 5);
//        typeToScoreMap.put("2", 10);
//        typeToScoreMap.put("3", 5);

//        int totalScore = userTitleList.stream()
//                .filter(userTitle -> userTitle.getUserAnswer() != null &&
//                        userTitle.getUserAnswer().equals(userTitle.getRealAnswer()))
//                .mapToInt(userTitle -> typeToScoreMap.getOrDefault(userTitle.getType(), 0)) // 使用映射获取分数，默认值为0
//                .sum();

        int totalScore = userTitleList.stream()
                .mapToInt(userTitle -> {
                    String userAnswer = userTitle.getUserAnswer();
                    String realAnswer = userTitle.getRealAnswer();
                    String type = userTitle.getType();

                    // 如果 userAnswer为 null，则直接不算分
                    if (userAnswer == null) {
                        return 0;
                    }

                    // 根据类型进行判断，以得到相应分数
                    if ("1".equals(type) || "3".equals(type)) {
                        return userAnswer.equals(realAnswer) ? 1 : 0; // 直接比较，得1分或0分
                    } else if ("2".equals(type)) {
                        return areAnswersEqualIgnoringOrder(userAnswer, realAnswer) ? 2 : 0; // 判断忽略顺序，得2分或0分
                    }

                    return 0; // 不支持的类型返回0分
                })
                .sum();


        // log.info("用户  {} 提交考试的考场id  {}  分数 {}", userId, kaochangId, totalScore); // 参数化日志记录

        kaochangUserService.lambdaUpdate()
                .set(KaochangUser::getScore, totalScore)
                .set(KaochangUser::getSubmitTime, LocalDateTime.now())
                .eq(KaochangUser::getUserId, userId)
                .eq(KaochangUser::getKaochangId, kaochangId)
                .update();

        return Result.success("交卷成功");
    }


    // 判断两个字符串内容相同但忽略顺序
    private static boolean areAnswersEqualIgnoringOrder(String answer1, String answer2) {
        String[] array1 = answer1.split(",");
        String[] array2 = answer2.split(",");

        // 对数组进行排序
        Arrays.sort(array1);
        Arrays.sort(array2);

        // 比较排序后的数组是否相等
        return Arrays.equals(array1, array2);
    }


    @ApiOperation("查看用户得分")
    @GetMapping("/getScore")
    public Result getScore(@ApiParam(required = true, value = "考场id 示例") Integer kaochangId,
                           @ApiParam(value = "用户id,参数名userId", required = true) Integer userId) {
//        User user = UserThreadLocalUtil.getUser();
//        Integer userId = user.getId();

        KaochangUser kaochangUser = kaochangUserService.lambdaQuery().eq(KaochangUser::getUserId, userId)
                .eq(KaochangUser::getKaochangId, kaochangId).one();
        Map<String, Object> map = new HashMap<>();
        map.put("user", kaochangUser);
        List<UserTitle> userTitleList = userTitleService.lambdaQuery()
                .eq(UserTitle::getUserId, userId)
                .eq(UserTitle::getKaochangId, kaochangUser.getKaochangId()).list();

        long right = userTitleList.stream().filter(s -> s.getUserAnswer() != null && areAnswersEqualIgnoringOrder(s.getUserAnswer(), s.getRealAnswer())).count();
        long error = userTitleList.stream().filter(s -> s.getUserAnswer() != null && !areAnswersEqualIgnoringOrder(s.getUserAnswer(), s.getRealAnswer())).count();
        long weida = userTitleList.stream().filter(s -> s.getUserAnswer() == null).count();
        map.put("rightTotal", right);
        map.put("errorTotal", error);
        map.put("nullTotal", weida);
        if (kaochangUser.getScore() == null) {
            return Result.error("您尚未参与考试,请考试完毕后查看得分!");
        } else {
            return Result.success(map);
        }
    }

    @ApiOperation("查看错题")
    @GetMapping("/getErrorTitle")
    public Result getErrorTitle(@ApiParam(required = true, value = "考场id") Integer kaochangId,
                                @ApiParam(value = "用户id,参数名userId", required = true) Integer userId) {
//        User user = UserThreadLocalUtil.getUser();
//        Integer userId = user.getId();


        KaochangUser kaochangUser = kaochangUserService.lambdaQuery().eq(KaochangUser::getUserId, userId)
                .eq(KaochangUser::getKaochangId, kaochangId).one();
        if (kaochangUser.getScore() == null) {
            return Result.error("您尚未参与考试,请考试完毕后查看错题!");
        }

        List<UserTitle> userTitleList = userTitleService.lambdaQuery()
                .eq(UserTitle::getUserId, userId)
                .eq(UserTitle::getKaochangId, kaochangId).list();

        List<UserTitle> titleList = userTitleList.stream().filter(s -> s.getUserAnswer() == null ||
                !areAnswersEqualIgnoringOrder(s.getUserAnswer(), s.getRealAnswer())).collect(Collectors.toList());


        //查询出每个类型题目的错题
        List<UserTitle> danxuanTitles = titleList.stream().filter(s -> s.getType().equals("1")).collect(Collectors.toList());
        List<UserTitle> duoxuanTitles = titleList.stream().filter(s -> s.getType().equals("2")).collect(Collectors.toList());
        List<UserTitle> panduanTitles = titleList.stream().filter(s -> s.getType().equals("3")).collect(Collectors.toList());


        List<Danxuan> danxuanList = redisTemplate.opsForList().range("danXuan", 0, -1);
        if (danxuanList == null || danxuanList.isEmpty()) {
            danxuanList = danxuanService.list();
        }
        List<Duoxuan> duoxuanList = redisTemplate.opsForList().range("duoXuan", 0, -1);
        if (duoxuanList == null || duoxuanList.isEmpty()) {
            duoxuanList = duoxuanService.list();
        }
        List<Panduan> panduanList = redisTemplate.opsForList().range("panDuan", 0, -1);
        if (panduanList == null || panduanList.isEmpty()) {
            panduanList = panduanService.list();
        }

        List<UserErrorDanxuanVo> danxuans = new ArrayList<>();
        List<UserErrorDuoxuanVo> duoxuans = new ArrayList<>();
        List<UserErrorPanduanVo> panduans = new ArrayList<>();

        //单选
        List<UserErrorDanxuanVo> collect1 = danxuanTitles.stream().map(s -> {
            UserErrorDanxuanVo userErrorDanxuanVo = new UserErrorDanxuanVo();
            BeanUtils.copyProperties(s, userErrorDanxuanVo);
            userErrorDanxuanVo.setKaochangId(kaochangId);
            userErrorDanxuanVo.setId(s.getTitleId());
            danxuans.add(userErrorDanxuanVo);
            return userErrorDanxuanVo;

        }).collect(Collectors.toList());

        // 将 danxuanList 转换为映射，键为 id
        Map<Integer, Danxuan> danxuanMap = danxuanList.stream()
                .collect(Collectors.toMap(Danxuan::getId, Function.identity()));

        // 使用 Stream 遍历 collect，并进行属性更新
        collect1.forEach(userErrorDanxuanVo -> {
            Danxuan danxuan = danxuanMap.get(userErrorDanxuanVo.getId());
            if (danxuan != null) {
                // 复制属性
                BeanUtils.copyProperties(danxuan, userErrorDanxuanVo, "id"); // 复制属性，排除 id 属性
            }
        });


        //多选
        List<UserErrorDuoxuanVo> collect2 = duoxuanTitles.stream().map(s -> {
            UserErrorDuoxuanVo userErrorDuoxuanVo = new UserErrorDuoxuanVo();
            BeanUtils.copyProperties(s, userErrorDuoxuanVo);
            userErrorDuoxuanVo.setKaochangId(kaochangId);
            userErrorDuoxuanVo.setId(s.getTitleId());
            duoxuans.add(userErrorDuoxuanVo);
            return userErrorDuoxuanVo;

        }).collect(Collectors.toList());

        // 将 duoxuanList 转换为映射，键为 id
        Map<Integer, Duoxuan> duoxuanMap = duoxuanList.stream()
                .collect(Collectors.toMap(Duoxuan::getId, Function.identity()));

        // 使用 Stream 遍历 collect，并进行属性更新
        collect2.forEach(userErrorDuoxuanVo -> {
            Duoxuan duoxuan = duoxuanMap.get(userErrorDuoxuanVo.getId());
            if (duoxuan != null) {
                // 复制属性
                BeanUtils.copyProperties(duoxuan, userErrorDuoxuanVo, "id"); // 复制属性，排除 id 属性
            }
        });


        //判断
        List<UserErrorPanduanVo> collect3 = panduanTitles.stream().map(s -> {
            UserErrorPanduanVo userErrorPanduanVo = new UserErrorPanduanVo();
            BeanUtils.copyProperties(s, userErrorPanduanVo);
            userErrorPanduanVo.setKaochangId(kaochangId);
            userErrorPanduanVo.setId(s.getTitleId());
            panduans.add(userErrorPanduanVo);
            return userErrorPanduanVo;

        }).collect(Collectors.toList());

        // 将 panduanList 转换为映射，键为 id
        Map<Integer, Panduan> panduanMap = panduanList.stream()
                .collect(Collectors.toMap(Panduan::getId, Function.identity()));

        // 使用 Stream 遍历 collect，并进行属性更新
        collect3.forEach(userErrorPanduanVo -> {
            Panduan panduan = panduanMap.get(userErrorPanduanVo.getId());
            if (panduan != null) {
                // 复制属性
                BeanUtils.copyProperties(panduan, userErrorPanduanVo, "id"); // 复制属性，排除 id 属性
            }
        });

        if (collect1.isEmpty() && collect2.isEmpty() && collect3.isEmpty()) {
            return Result.error("恭喜" + kaochangUser.getName() + "您的答案全部正确！");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("danxuan", collect1);
        map.put("duoxuan", collect2);
        map.put("panduan", collect3);


        return Result.success(map);

    }


    @ApiOperation("用户端清除成绩")
    @GetMapping("/clear")
    @Transactional
    public Result clear(@ApiParam(required = true, value = "考场id 示例") Integer kaochangId,
                        @ApiParam(value = "用户id,参数名userId", required = true) Integer userId) {


        KaochangUser kaochangUser = kaochangUserService.lambdaQuery().eq(KaochangUser::getUserId, userId).eq(KaochangUser::getKaochangId, kaochangId).one();

        if (kaochangUser.getScore() == null) {
            return Result.error("清除成绩失败,请确认是否参与考试并提交试卷！");
        }
        //更新成绩表
        kaochangUserService.lambdaUpdate()
                .set(KaochangUser::getScore, null)
                .set(KaochangUser::getLoginTime, null)
                .set(KaochangUser::getSubmitTime, null)
                .eq(KaochangUser::getUserId, userId).eq(KaochangUser::getKaochangId, kaochangId)
                .update();
        LambdaQueryWrapper<UserTitle> lqw = new LambdaQueryWrapper<>();
        //删除题目表
        lqw.eq(UserTitle::getUserId, userId).eq(UserTitle::getKaochangId, kaochangId);
        userTitleService.remove(lqw);
        return Result.success("清除成绩成功!");

    }


    @ApiOperation("根据考场id查询考场信息")
    @GetMapping("/updateKaochang")
    public Result updateKaochang(@ApiParam(value = "考场id", required = true) Integer id) {

        Kaochang kaochang = kaochangService.lambdaQuery().eq(Kaochang::getId, id).one();

        if (kaochang == null) {
            return Result.error("考场不存在");
        } else {
            KaochangVo kaochangVo = new KaochangVo();
            BeanUtils.copyProperties(kaochang, kaochangVo);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            kaochangVo.setStartTime(kaochang.getStartTime().format(formatter));
            kaochangVo.setEndTime(kaochang.getEndTime().format(formatter));
            kaochangVo.setCreateTime(kaochang.getCreateTime().format(formatter));
            return Result.success(kaochangVo);
        }

    }


}
